package egar

import "github.com/gorilla/websocket"

type OutPacketType = int8

const (
	OutPacketTypeStartGameOk OutPacketType = iota + 1
	OutPacketTypeUpdateRanking
	OutPacketTypeUpdateVisibleData
	OutPacketTypeChatMessage
	OutPacketTypeDead
)

type protocol struct {
	player *Player
	buffer *Buffer
}

func newProtocol(player *Player) *protocol {
	return &protocol{
		player: player,
		buffer: NewBuffer(1 * 1024 * 1024), // 1MB
	}
}

func (p *protocol) startGameOk() {
	x, y := RandomPosition()
	cell := NewCellBall(x, y, p.player.Color, p.player.game.config.CellInitMass, p.player)
	p.player.game.gameMap.hatchBall(cell)
	p.player.State = PlayerStatePlaying

	p.buffer.Clear()
	p.buffer.WriteInt8(OutPacketTypeStartGameOk)
	// game map boundary
	p.buffer.WriteFloat32(0, false)                                           // left
	p.buffer.WriteFloat32(0, false)                                           // top
	p.buffer.WriteFloat32(float32(p.player.game.config.GameMapWidth), false)  // right
	p.buffer.WriteFloat32(float32(p.player.game.config.GameMapHeight), false) // bottom
	p.player.Connection.WriteMessage(websocket.BinaryMessage, p.buffer.ReadBytes(p.buffer.ReadableBytes(), false))
}

func (p *protocol) updateVisibleData() {
	p.buffer.Clear()

	p.buffer.WriteInt8(OutPacketTypeUpdateVisibleData)

	p.buffer.WriteFloat32(float32(p.player.TotalMass), false)

	p.buffer.WriteFloat32(float32(p.player.ViewScale), false)
	p.buffer.WriteFloat32(float32(p.player.ViewCenterX), false)
	p.buffer.WriteFloat32(float32(p.player.ViewCenterY), false)
	p.buffer.WriteFloat32(float32(p.player.ViewWidth), false)
	p.buffer.WriteFloat32(float32(p.player.ViewHeight), false)

	p.buffer.WriteInt32(int32(len(p.player.VisibleBalls)), false)

	for _, ball := range p.player.VisibleBalls {
		p.buffer.WriteInt8(ball.Type)
		p.buffer.WriteUint32(ball.ID, false)
		p.buffer.WriteFloat32(float32(ball.X), false)
		p.buffer.WriteFloat32(float32(ball.Y), false)
		p.buffer.WriteFloat32(float32(ball.Mass), false)
		p.buffer.WriteFloat32(float32(ball.Radius), false)
		p.buffer.WriteUint32(ball.Color, false)
	}

	p.player.Connection.WriteMessage(websocket.BinaryMessage, p.buffer.ReadBytes(p.buffer.ReadableBytes(), false))
}
